iT邦幫忙

0

從零打造輔大課表神器:Chrome Extension 開發實戰 30 天 - Day 17

  • 分享至 

  • xImage
  •  

Day 17:Chrome Extension 實作篇 - 組件協作與基礎消息傳遞

🎯 系列目標:用 30 天時間,從零開始打造一個專屬輔大學生的課表生成 Chrome 擴充功能

👨‍💻 作者:輔大智慧資安 412580084

📅 Day 17:Chrome Extension 實作篇 - 組件協作與基礎消息傳遞

🔄 從單獨功能到協同工作

昨天我們學會了在網頁中注入「我的課表」按鈕,今天我們要深入學習如何讓 Content Script 與 Background Script 協同工作,建立基本的自動化課表生成流程!

📋 學習目標

今天我們要完成:

  1. 🧠 理解 Chrome Extension 各組件的協作原理
  2. 🔄 設計基本的消息傳遞流程
  3. 🎯 建立簡單的背景處理機制
  4. 🧪 完成基礎整合測試

🧠 理解組件協作原理

1.1 為什麼需要組件協作?

在前面的學習中,我們分別建立了三個主要組件:

  • Content Script:負責網頁互動(注入按鈕、顯示通知)
  • Background Script:負責核心邏輯(處理流程、管理資料)
  • Popup Script:負責擴充功能介面(用戶操作)

1.2 協作模式設計

我們採用「中央控制」模式:

  • Content Script 和 Popup Script 只負責用戶介面
  • 所有複雜邏輯都在 Background Script 中處理
Content Script ──────┐
                     ▼
               Background Script
                     ▲
Popup Script ────────┘

1.3 責任分工

模組 責任說明
Content Script 1. 注入按鈕到網頁2. 監聽用戶點擊3. 發送消息給 Background4. 顯示處理結果給用戶
Background Script 1. 接收來自 Content/Popup 的消息2. 執行核心業務邏輯3. 管理分頁和資料4. 協調各組件工作
Popup Script 1. 提供用戶操作介面2. 發送消息給 Background3. 顯示處理狀態和結果

🔄 基本消息傳遞系統

2.1 流程設計概念

在開始實作之前,我們先了解整個課表生成的基本流程:

flowchart TD
    A[用戶點擊「我的課表」按鈕] --> B[Content Script 發送消息]
    B --> C[Background Script 接收處理]
    C --> D[執行基本處理流程]
    D --> E[回應處理結果]
    E --> F[顯示結果給用戶]

2.2 Background Script 基本架構

這是整個系統的核心,負責接收和處理消息:

// Background Script 的基本消息監聽器
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
  console.log('📨 Background 收到消息:', request);
  
  // 檢查消息類型
  if (request.action === 'generateSchedule') {
    console.log('🚀 開始課表生成流程');
    handleBasicScheduleGeneration(request, sendResponse);
    return true; // 保持消息通道開放
  }
  
  // 其他消息類型處理...
  console.log('❓ 未知的消息類型:', request.action);
  sendResponse({ success: false, error: '未知的操作類型' });
});

說明:

  • onMessage.addListener 監聽來自其他組件的消息
  • request.action 用來區分不同的操作類型
  • return true 保持消息通道開放,允許非同步回應
  • 詳細的 console.log 方便除錯

2.3 基本處理函數

將課表生成流程簡化為基本版本,透過chrome.tabs.create()可以開啟新分頁:

// 基本的課表生成處理函數
async function handleBasicScheduleGeneration(request, sendResponse) {
  try {
    console.log('🗺️ 開始基本課表生成流程');
    
    // 步驟 1:記錄請求資訊
    console.log('📝 步驟 1: 記錄用戶請求');
    console.log('來源頁面:', request.data.url);
    console.log('請求時間:', request.data.timestamp);
    
    // 步驟 2:模擬基本處理
    console.log('⚙️ 步驟 2: 執行基本處理');
    await simulateProcessing();
    
    // 步驟 3:開啟結果頁面
    console.log('🎉 步驟 3: 開啟課表結果頁面');
    chrome.tabs.create({ url: 'schedule.html' });
    
    // 成功回應
    sendResponse({ 
      success: true, 
      message: '基本課表生成流程完成',
      data: {
        processedAt: new Date().toISOString(),
        fromUrl: request.data.url
      }
    });
    
  } catch (error) {
    console.error('❌ 課表生成流程失敗:', error);
    sendResponse({ 
      success: false, 
      error: error.message,
      timestamp: new Date().toISOString()
    });
  }
}

// 模擬處理時間
function simulateProcessing() {
  return new Promise(resolve => {
    console.log('⏳ 模擬處理中...');
    setTimeout(() => {
      console.log('✅ 模擬處理完成');
      resolve();
    }, 2000); // 模擬 2 秒處理時間
  });
}

🎯 Content Script 優化版本

3.1 專注於使用者介面

由於 Background Script 現在處理所有複雜邏輯,Content Script 可以專注於使用者介面:

// 優化的按鈕點擊處理
function handleScheduleButtonClick(event) {
  event.preventDefault();
  console.log('📊 「我的課表」按鈕被點擊');
  
  const button = event.target;
  const originalText = button.textContent;
  
  // 更新按鈕狀態
  setButtonProcessing(button);
  
  // 發送消息給 background script
  chrome.runtime.sendMessage({
    action: 'generateSchedule',
    source: 'webpage',
    data: {
      url: window.location.href,
      timestamp: new Date().toISOString()
    }
  }, (response) => {
    // 處理回應並恢復按鈕狀態
    handleScheduleResponse(button, originalText, response);
  });
}

// 設定按鈕處理中狀態
function setButtonProcessing(button) {
  button.textContent = '⏳ 處理中...';
  button.style.pointerEvents = 'none';
  button.style.opacity = '0.7';
}

// 處理背景腳本的回應
function handleScheduleResponse(button, originalText, response) {
  // 恢復按鈕狀態
  button.textContent = originalText;
  button.style.pointerEvents = 'auto';
  button.style.opacity = '1';
  
  if (response && response.success) {
    console.log('✅ 課表生成成功');
    showNotification('課表生成成功!正在開啟結果頁面...', 'success');
  } else {
    console.error('❌ 課表生成失敗:', response?.error);
    showNotification('課表生成失敗:' + (response?.error || '未知錯誤'), 'error');
  }
}

🧪 整合測試

4.1 測試準備

🔧 步驟 1:更新檔案

  • 更新 background.js:加入今天學習的基本流程控制邏輯
  • 更新 content.js:優化按鈕互動處理

🔄 步驟 2:重新載入擴充功能

在 Chrome 擴充功能管理頁面重新載入

4.2 測試流程

🧪 步驟 3:功能測試

  1. 登入輔大學生入口網https://portal.fju.edu.tw/student/
  2. 點擊「我的課表」按鈕:觀察按鈕變為「處理中...」
    7
  3. 觀察處理過程
    • 按鈕狀態變化(約2秒)
    • 等待處理完成
  4. 檢查結果
    • 應該會開啟 schedule.html 頁面(目前尚未建立因此以下畫面為正常的)
      0

    • 檢查日誌是否為以下情況即成功 (在schedule.html 中按下 F12 檢查)
      1


🎯 明日預告

Day 18 我們將深入學習 Background Script 分頁控制機制


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言